package org.example.netty.protocol;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import org.example.utils.LogUtils;
import org.junit.Test;

import java.io.ByteArrayInputStream;

public class ProtobufDemo {

    public MsgProtos.Msg buildMsg() {
        MsgProtos.Msg.Builder builder = MsgProtos.Msg.newBuilder();
        builder.setId(10);
        builder.setContent("hello john");
        return builder.build();
    }

    @Test
    public void test1() {
        MsgProtos.Msg msg = buildMsg();
        // protobuf序列化
        try {
            // 此方法有个弊端，会先把数据读到内存
            byte[] data = msg.toByteArray();

            // 此处可以将data用于网络传输
            ByteOutputStream bout = new ByteOutputStream();
            bout.write(data);

            data = bout.toByteArray();

            msg = MsgProtos.Msg.parseFrom(data);
            LogUtils.info("id :" + msg.getId());
            LogUtils.info("content :" + msg.getContent());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 此方式存在粘包和拆包问题
     */
    @Test
    public void test2() {
        MsgProtos.Msg msg = buildMsg();
        ByteOutputStream bout = new ByteOutputStream();

        try {
            msg.writeTo(bout);
            ByteArrayInputStream bain = new ByteArrayInputStream(bout.toByteArray());
            msg = MsgProtos.Msg.parseFrom(bain);

            LogUtils.info("id :" + msg.getId());
            LogUtils.info("content :" + msg.getContent());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 解决粘包和拆包问题
     */
    @Test
    public void test3() {
        MsgProtos.Msg msg = buildMsg();
        ByteOutputStream bout = new ByteOutputStream();

        try {
            // 此方法会添加一个字节长度
            msg.writeDelimitedTo(bout);
            ByteArrayInputStream bain = new ByteArrayInputStream(bout.toByteArray());
            msg = MsgProtos.Msg.parseDelimitedFrom(bain);

            LogUtils.info("id :" + msg.getId());
            LogUtils.info("content :" + msg.getContent());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
